﻿using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;

namespace TopShelfServiceBatchInstaller
{
    public class TopShelfInstallerItem : INotifyPropertyChanged
    {
        private InstallStatus _installStatus;
        private bool _shouldInstall = true;
        public string Name { get; set; }
        public string SourceDir { get; set; }

        public string Version { get; set; }

        public InstallStatus InstallStatus
        {
            get => _installStatus;
            set
            {
                _installStatus = value;
                OnPropertyChanged();
            }
        }

        public bool ShouldInstall
        {
            get => _shouldInstall;
            set
            {
                _shouldInstall = value;
                OnPropertyChanged();
            }
        }

        public string PreviousVersion { get; set; }


        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public async Task<string> InstallAsync(string appDir)
        {
            string runMessage = null;
            await Task.Run(() =>
             {
                 // Copy install folder to app folder
                 var dstDir = Path.Combine(appDir, Name);
                 Directory.CreateDirectory(dstDir);
                 CopyDirRecursively(SourceDir, dstDir);

                 // Run install command
                 var cmd = $"{Name}.exe install start";
                 runMessage = RunCmd(dstDir, cmd);

                 InstallStatus = InstallStatus.AlreadyInstall;
                 ShouldInstall = false;

             });
            return runMessage;
        }

        public async Task<string> UninstallPreviousAsync(string appDir)
        {
            string runMessage = null;
            await Task.Run(() =>
            {
                // Run uninstall command
                var dstDir = Path.Combine(appDir, Name);
                var cmd = $"{Name}.exe stop uninstall";
                runMessage = RunCmd(dstDir, cmd);

                // Remove dir
                Helper.DeleteDirectory(dstDir);
            });

            InstallStatus = InstallStatus.FirstInstall;
            PreviousVersion = Version;
            return runMessage;
        }


        public static string RunCmd(string workingDir, string command)
        {
            ProcessStartInfo proStart = new ProcessStartInfo
            {
                RedirectStandardOutput = true,
                FileName = "cmd.exe",
                WorkingDirectory = workingDir,
                Arguments = $"/c {command}",
                WindowStyle = ProcessWindowStyle.Hidden
            };
            Process pro = new Process { StartInfo = proStart };
            pro.Start();


            var sr = pro.StandardOutput;
            var content = sr.ReadToEnd();
            return content;
        }

        private static void CopyDirRecursively(string sourceDir, string dstDir)
        {
            //Now Create all of the directories
            foreach (string dirPath in Directory.GetDirectories(sourceDir, "*",
                SearchOption.AllDirectories))
                Directory.CreateDirectory(dirPath.Replace(sourceDir, dstDir));

            //Copy all the files & Replaces any files with the same name
            foreach (string newPath in Directory.GetFiles(sourceDir, "*.*",
                SearchOption.AllDirectories))
                File.Copy(newPath, newPath.Replace(sourceDir, dstDir), true);
        }

    }
}